Categories
Vue 3

Vuex 4 — Actions

Spread the love

Vuex 4 is in beta and it’s subject to change.

Vuex is a popular state management library for Vue.

Vuex 4 is the version that’s made to work with Vue 3.

In this article, we’ll look at how to use Vuex 4 with Vue 3.

Actions

In Vuex 4, actions are similar to mutations.

The differences are that actions commit mutations and actions can have async operations.

To create an action, we can add an actions property to our store.

For instance, we can write:

<!DOCTYPE html>  
<html lang="en">  
  <head>  
    <script src="https://unpkg.com/vue@next"></script>  
    <script src="https://unpkg.com/vuex@4.0.0-beta.4/dist/vuex.global.js"></script>  
    <title>App</title>  
  </head>  
  <body>  
    <div id="app">  
      <button @click="increment">increment</button>  
      <p>{{count}}</p>  
    </div>  
    <script>  
      const store = new Vuex.Store({  
        state: {  
          count: 0  
        },  
        mutations: {  
          increment(state) {  
            state.count++;  
          }  
        },  
        actions: {  
          increment(context) {  
            context.commit("increment");  
          }  
        }  
      });  
      const app = Vue.createApp({  
        methods: {  
          increment() {  
            this.$store.dispatch("increment");  
          }  
        },  
        computed: {  
          count() {  
            return this.$store.state.count;  
          }  
        }  
      });  
      app.use(store);  
      app.mount("#app");  
    </script>  
  </body>  
</html>

We created a Vuex store with an actions property that has the increment method in it.

It takes the comtext parameter with the commit method to commit mutations.

To dispatch the action in our component, we call this.$store.dispatch with the action name.

We can perform async operations in an action.

For example, we can write:

<!DOCTYPE html>  
<html lang="en">  
  <head>  
    <script src="https://unpkg.com/vue@next"></script>  
    <script src="https://unpkg.com/vuex@4.0.0-beta.4/dist/vuex.global.js"></script>  
    <title>App</title>  
  </head>  
  <body>  
    <div id="app">  
      <button @click="increment">increment</button>  
      <p>{{count}}</p>  
    </div>  
    <script>  
      const store = new Vuex.Store({  
        state: {  
          count: 0  
        },  
        mutations: {  
          increment(state) {  
            state.count++;  
          }  
        },  
        actions: {  
          incrementAsync({ commit }) {  
            setTimeout(() => {  
              commit("increment");  
            }, 1000);  
          }  
        }  
      });  
      const app = Vue.createApp({  
        methods: {  
          increment() {  
            this.$store.dispatch("incrementAsync");  
          }  
        },  
        computed: {  
          count() {  
            return this.$store.state.count;  
          }  
        }  
      });  
      app.use(store);  
      app.mount("#app");  
    </script>  
  </body>  
</html>

We called commit inside the setTimeout callback to delay the action dispatch by a second.

Also, we can dispatch actions with a payload.

For instance, we can write:

<!DOCTYPE html>  
<html lang="en">  
  <head>  
    <script src="https://unpkg.com/vue@next"></script>  
    <script src="https://unpkg.com/vuex@4.0.0-beta.4/dist/vuex.global.js"></script>  
    <title>App</title>  
  </head>  
  <body>  
    <div id="app">  
      <button @click="increment">increment</button>  
      <p>{{count}}</p>  
    </div>  
    <script>  
      const store = new Vuex.Store({  
        state: {  
          count: 0  
        },  
        mutations: {  
          increment(state, payload) {  
            state.count += payload.amount;  
          }  
        },  
        actions: {  
          incrementAsync({ commit }, payload) {  
            setTimeout(() => {  
              commit("increment", payload);  
            }, 1000);  
          }  
        }  
      });  
      const app = Vue.createApp({  
        methods: {  
          increment() {  
            this.$store.dispatch("incrementAsync", { amount: 2 });  
          }  
        },  
        computed: {  
          count() {  
            return this.$store.state.count;  
          }  
        }  
      });  
      app.use(store);  
      app.mount("#app");  
    </script>  
  </body>  
</html>

We added a payload parameter to the incrementAsync action to accept payloads in our action.

Then we pass in an object as the 2nd argument to the this.$store.dispatch method to dispatch our action.

We can also pass in an object with the type property and arbitrary properties that will be included in the payload:

<!DOCTYPE html>  
<html lang="en">  
  <head>  
    <script src="https://unpkg.com/vue@next"></script>  
    <script src="https://unpkg.com/vuex@4.0.0-beta.4/dist/vuex.global.js"></script>  
    <title>App</title>  
  </head>  
  <body>  
    <div id="app">  
      <button @click="increment">increment</button>  
      <p>{{count}}</p>  
    </div>  
    <script>  
      const store = new Vuex.Store({  
        state: {  
          count: 0  
        },  
        mutations: {  
          increment(state, payload) {  
            state.count += payload.amount;  
          }  
        },  
        actions: {  
          incrementAsync({ commit }, payload) {  
            setTimeout(() => {  
              commit("increment", payload);  
            }, 1000);  
          }  
        }  
      });  
      const app = Vue.createApp({  
        methods: {  
          increment() {  
            this.$store.dispatch({ type: "incrementAsync", amount: 2 });  
          }  
        },  
        computed: {  
          count() {  
            return this.$store.state.count;  
          }  
        }  
      });  
      app.use(store);  
      app.mount("#app");  
    </script>  
  </body>  
</html>

The type is the name of the action and the other properties will end up in the payload object in the 2nd argument of the incrementAsync action.

Conclusion

We can create actions to commit mutations and run async code with Vuex 4.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *